home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
simcode.arc
/
LOGIN.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1985-01-19
|
13KB
|
495 lines
{$symtab-,$linesize:131,$pagesize:86,$debug-,
$title:'LOGIN.PAS -- Script Interpreter'}
{ COPYRIGHT @ 1982
Jim Holtman and Eric Holtman
35 Dogwood Trail
Randolph, NJ 07869
(201) 361-3395
}
module script;
type
menu_c = super array[1..*] of lstring(40);
instruction = record
state, action, yes, no : integer;
act_str : lstring(40);
end;
var
strs : array[1..20] of array[1..20] of ^lstring;
max_sys : integer;
menu : menu_c(20);
cancel_command [external] : boolean;
inst : array[1..200] of ^instruction;
been_read_yet : boolean;
stack : array[1..20] of integer;
stack_ptr : integer;
time_out_value : word;
log_file [external] : file of char;
log_flag [external] : boolean;
script_verbose [external] : boolean;
value been_read_yet := false;
stack_ptr := 0;
time_out_value := 15; {$include:'token.h'}
{$include:'graph.inc'}
{$include:'comm.inc'}
{$include:'simterm.inc'}
{$include:'util.inc'}
procedure parse_file(var s : lstring);
external;
procedure push_label(i : integer);
begin
stack_ptr := stack_ptr + 1;
stack[stack_ptr] := i;
end;
function pop_label : integer;
begin
if (stack_ptr > 0) then begin
pop_label := stack[stack_ptr];
stack_ptr := stack_ptr - 1;
end
else pop_label := -1;
end;
function menuit(var choices : menu_c;
const title : lstring ) : integer;
external;
procedure dial(var s:lstring);
external;
function getc(exit_flag : LOOP_FLAG) : integer;
external;
procedure putchar(ch : char);
external;
procedure ck(a : integer;
const b : string);
external;
procedure savescreen;
external;
procedure restorescreen;
external;
function do_cancel : boolean;
external;
function find_state(st : integer) : integer;
var
i : integer;
begin
for i := 1 to max_sys do BEGIN
if (inst[i]^.state = st) then begin
find_state := i;
return;
end END;
find_state := -1;
end;
function find_label(const st : lstring) : integer;
var
i : integer;
begin
for i := 1 to max_sys do BEGIN
if ((inst[i]^.action = A_LABEL) and (st = inst[i]^.act_str)) then begin
find_label := i;
return;
end END;
find_label := -1;
end;
function expect(const str : lstring) : boolean;
var
i : integer;
t : word;
inch : char;
ch : integer;
back : char;
time_out : boolean;
begin
cancel_command := false;
t := timer;
time_out := false;
while (time_out = false) do begin
i := 1;
while (i <= ord(str.len)) or (str.len = 0) do begin
t := timer;
while (timer - t < time_out_value) do begin
if do_cancel then return;
ch := getc(EXIT);
if (ch > -1) then break;
end;
if log_flag and (ch > -1) then begin
log_file^ := chr(ch);
put(log_file);
end;
if (ch > -1) then putchar(chr(ch));
if (timer - t >= time_out_value) then begin
time_out := true;
break;
end;
if (str.len > 0) then BEGIN
if (ch <> ord(str[i])) then begin
if (ch = ord(str[1])) then i := 2
else i := 1;
cycle;
end END;
i := i + 1;
end;
if (i = ord(str.len)+1) and (str.len <> 0) then begin
expect := true;
return;
end;
end;
expect := false;
end;
function look_for(var strs : menu_c) : integer;
var
i : integer;
t : word;
inch : char;
ch : integer;
back : char;
time_out : boolean;
cnt : integer;
ptr : array[1..20] of integer;
num_strs : integer;
begin
cancel_command := false;
t := timer;
time_out := false;
num_strs := 0;
for cnt := 1 to 20 do begin
ptr[cnt] := 0;
if (strs[cnt].len > 0) then num_strs := num_strs + 1;
end;
while (time_out = false) do begin
for cnt := 1 to num_strs do begin
if (strs[cnt].len > 0) and (strs[cnt].len <= wrd(ptr[cnt])) then begin
look_for := cnt;
return;
end;
ptr[cnt] := ptr[cnt] + 1;
end;
t := timer;
while (timer - t < time_out_value) do begin
if do_cancel then begin
look_for := 0;
return;
end;
ch := getc(EXIT);
if (ch > -1) then break;
end;
if log_flag and (ch > -1) then begin
log_file^ := chr(ch);
put(log_file);
end;
if (ch > -1) then putchar(chr(ch));
if (timer - t >= time_out_value) then begin
time_out := true;
break;
end;
for cnt := 1 to num_strs do begin
if (ch <> ord(strs[cnt,ptr[cnt]])) then begin
if (ch = ord(strs[cnt,1])) then ptr[cnt] := 1
else ptr[cnt] := 0;
end;
end;
end;
look_for := 0;
end;
procedure send_parse(const s : lstring);
var
i : integer;
sum : word;
char_send : char;
const
BACKSL = '\';
CR = chr(13);
LF = chr(10);
begin
i := 1;
while (i <= ord(s.len)) do begin
if (s[i] = '\') then begin
case s[i+1] of
'\': begin
send(BACKSL);
i := i + 1;
end;
'B': begin
eval(breaker);
i := i+1;
end;
'm': begin
send(CR);
i := i + 1;
end;
'j': begin
send(LF);
i := i + 1;
end;
'1': begin
sleep(1);
i := i + 1;
end;
'c': return;
'o': begin
sum := 0;
for i:=i+2 to ord(s.len) do
if s[i] in ['0'..'7'] then
sum := sum*8+wrd(s[i])-wrd('0')
else break;
i := i-1;
char_send := chr(sum and #FF);
send(char_send);
end;
otherwise ;
end;
end
else send(s[i]);
i := i + 1;
end;
send(CR);
end;
function conn(i : integer) : integer;
var
l : integer;
num : lstring(40);
j : integer;
strs : menu_c(20);
lf : integer;
const
cr = chr(13);
begin {riteln('parsing
',i,inst[i]^.state,inst[i]^.action,inst[i]^.yes,inst[i]^.no,inst[i]^.act_str);}
if do_cancel then return;
if (inst[i]^.yes < 0) then begin
sleep(4);
restorescreen;
conn := -1;
return;
end;
if (inst[i]^.action = A_TOGGLE_TR) then begin
toggle_tr;
if (script_verbose) then writeln('Hanging up phone');
end
else if (inst[i]^.action = A_OPENLOG) then begin
copylst(inst[i]^.act_str, num);
parse_file(num);
assign(log_file,num);
rewrite(log_file);
log_flag := true;
if (script_verbose) then writeln('Opening ',num,' for logging');
end
else if (inst[i]^.action = A_CLOSELOG) then begin
if (log_flag) then begin
if (script_verbose) then writeln('Closing LOGFILE');
close(log_file);
log_flag := false;
end
else if (script_verbose) then writeln( 'Error: no LOGFILE to close, INST = ',i);
end
else if (inst[i]^.action = A_DIAL) then begin
copylst(inst[i]^.act_str, num);
dial(num);
end
else if (inst[i]^.action = A_SETTIME) then begin
if (script_verbose) then writeln('Set time-out to ',inst[i]^. act_str);
if (decode(inst[i]^.act_str, time_out_value) = false) then begin
if (script_verbose) then writeln('Illegal settime value; ',inst[ i]^.act_str);
time_out_value := 15;
end;
end
else if (inst[i]^.action = A_CASE) then begin
if (script_verbose) then write('Case: ');
for l := 1 to 20 do begin
if (inst[find_state(inst[i]^.yes+l-1)]^.action = TOK_CASEEND) then begin
strs[l].len := 0;
lf := look_for(strs);
if (script_verbose) then begin
writeln;
if (lf > 0) then writeln('Got ',strs[lf])
else writeln('got OTHERWISE');
end;
conn := find_state(inst[find_state(inst[i]^.yes+lf-1)]^.yes);
return;
end;
copylst(inst[find_state(inst[i]^.yes+l-1)]^.act_str,strs[l]);
if (script_verbose) then write('"',strs[l],'" ');
end;
end
else if (inst[i]^.action = A_INPUT) then begin
write(inst[i]^.act_str);
readln(num);
send_parse(num);
end
else if (inst[i]^.action = A_EXPECT) then begin
if (inst[i]^.act_str.len > 0) then begin
if (script_verbose) then writeln('Looking for "',inst[i]^. act_str,'"') end
else writeln('Looking for nothing in particular, just a time-out');
if (expect(inst[i]^.act_str) = false) then begin
if (script_verbose) then writeln('Failed. Could not receive "', inst[i]^.act_str,'"');
sleep(2);
conn := find_state(inst[i]^.no);
return;
end;
if (script_verbose) then writeln('Got it');
end
else if (inst[i]^.action = A_SEND) then begin
if (script_verbose) then writeln('Sending "',inst[i]^.act_str,'"');
send_parse(inst[i]^.act_str);
end
else if (inst[i]^.action = A_SAY) then begin
writeln(inst[i]^.act_str);
end
else if (inst[i]^.action = A_LABEL) then begin
{ NO - OP }
end
else if (inst[i]^.action = A_NGOTO) then begin
{ NO - OP }
end
else if (inst[i]^.action = A_LGOTO) then begin
if (script_verbose) then writeln('Goto "',inst[i]^.act_str,'"');
conn := find_label(inst[i]^.act_str);
return;
end
else if (inst[i]^.action = A_GOSUB) then begin
if (script_verbose) then writeln('Gosub "',inst[i]^.act_str,'"');
push_label(inst[i]^.state + 1);
conn := find_label(inst[i]^.act_str);
return;
end
else if (inst[i]^.action = A_RETURN) then begin
if (script_verbose) then writeln('Return');
l := pop_label;
if (l < 0) then begin
writeln('Return without gosub, instruction number ',inst[i]^. state);
return;
end
else conn := find_state(l);
return;
end;
conn := find_state(inst[i]^.yes);
return;
end;
procedure compile(var s : lstring);
external;
procedure login [public];
var
i,j,l : integer;
k : byte;
sfile : text;
buf : lstring(128);
cbuf : lstring(128);
key : lstring(8);
ch : char;
script_file [external] : lstring(20);
first_script [external] : lstring(20);
cryptic : boolean;
begin
cancel_command := false;
savescreen;
if (not been_read_yet) then begin
been_read_yet := true;
assign(sfile, script_file);
reset(sfile);
readln(sfile, buf);
if (buf <> '#compiled') then begin
close(sfile);
compile(script_file);
assign(sfile, script_file);
reset(sfile);
readln(sfile, buf);
end;
max_sys := 0;
while not eof(sfile) do begin
max_sys := max_sys + 1;
new(inst[max_sys]);
readln(sfile, inst[max_sys]^.state, inst[max_sys]^.action, inst[ max_sys]^.yes, inst[max_sys]^.no,
inst[ max_sys]^.act_str);
delete(inst[max_sys]^.act_str,1,1);
end;
end;
if (first_script.len = 0) then begin
j := 0;
for i := 1 to max_sys do begin
if (inst[i]^.action = A_ENTRY) then begin
j := j + 1;
copylst(inst[i]^.act_str, menu[j]);
end;
end;
menu[j+1].len := 0;
i := menuit(menu, 'Scripts available');
if (i > 0) then begin
{writeln('Executing script ',menu[i]);}
for j := 1 to max_sys do begin
if ((menu[i] = inst[j]^.act_str) and (inst[j]^.action = A_ENTRY)) then break;
end;
i := j;
end;
end
else BEGIN
for i := 1 to max_sys do BEGIN
if ((first_script = inst[i]^.act_str) and (inst[i]^.action = A_ENTRY)) then break END END;
if ((i = 0) or (i=max_sys+1) ) then begin
restorescreen;
return;
end;
restorescreen;
i := find_state(inst[i]^.yes);
while (i >= 0) do i := conn(i);
end;
procedure alogin [public];
begin
end; end.